#include <iostream>

class Op {
    public:
        Op(const char *name) : name_(name) {}
        virtual ~Op() {}

        virtual int Start() = 0;
        virtual int Feed() = 0;
        virtual int Stop() = 0;

        std::string &Name() { return name_; }
    private:
        std::string name_;
};

class OpPost : public Op {
    public:
        OpPost() : Op("post") { }

        ~OpPost() {
            std::cout << "[ OpPost ] destroyed <<< name: " << Name() << std::endl;
        }

        int Start() {
            std::cout << "[ OpPost ] start <<< name: " << Name() << std::endl;
            return 0;
        }

        int Feed() {
            std::cout << "[ OpPost ] feed <<< name: " << Name() << std::endl;
            return 0;
        }

        int Stop() {
            std::cout << "[ OpPost ] stop <<< name: " << Name() << std::endl;
            return 0;
        }
};

class OpSSC : public Op {
    public:
        OpSSC() : Op("ssc") { }

        ~OpSSC() {
            std::cout << "[ OpSSC ] destroyed <<< name: " << Name() << std::endl;
        }

        int Start() {
            std::cout << "[ OpSSC ] start <<< name: " << Name() << std::endl;
            return 0;
        }

        int Feed() {
            std::cout << "[ OpSSC ] feed <<< name: " << Name() << std::endl;
            return 0;
        }

        int Stop() {
            std::cout << "[ OpSSC ] stop <<< name: " << Name() << std::endl;
            return 0;
        }
};

class Plugin {
    public:
        virtual ~Plugin() {}
        virtual Op *CreateOp() = 0;
};

class PluginPost : public Plugin {
    public:
        Op *CreateOp() { return new OpPost; }
};

class PluginSSC : public Plugin {
    public:
        Op *CreateOp() { return new OpSSC; }
};

static void doOp(Op *op) {
    op->Start();
    op->Feed();
    op->Stop();

    delete op;
}

int main() {
    Plugin *plugin = nullptr;

    std::cout << "[ main ] pre... " << std::endl;

    plugin = new PluginPost;
    doOp(plugin->CreateOp());
    delete plugin;

    plugin = new PluginSSC;
    doOp(plugin->CreateOp());
    delete plugin;

    return 0;
}
